#include <ranges>

#include <winsock2.h>
#include <ws2tcpip.h>

//#include <format>
#include <filesystem>
#include <Windows.h>
#include <shellapi.h>
#include <tchar.h>

#include "code_trans.h"
#include "print.h"
#include "thread_pool.h"
#include "nlohmann/json_fwd.hpp"
#include "nlohmann/json.hpp"
#include "resource.h"
#include "udp_receiver.h"

import utils;
import config;
import watch_dog;


auto& g_config = get_config();








import display_impl;




int main(int argc, char** argv)
{

    //std::cout << process::powershell("Get-Process") << std::endl;

    watch_dog dog(argc, argv);

    const auto receiver = std::make_shared<udp_receiver>(g_config.udp_receiver_parameters);
    dlog = Log(std::make_shared<udp_sender>(g_config.udp_reply_parameters));
    //dlog.slots().emplace_back([](std::string_view s)
    //    {
    //        ShowBalloon(L"Message", Utf8ToWideChar({ reinterpret_cast<const char8_t*>(s.data()), s.size() }));
    //    });
    return Display_Exec([&]
    {
	    const auto messages = receiver->peek_all_message();
        for (auto& message : messages)
        {
            process_message(dlog, message);
        }
        dog.tick();
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    });

}




std::vector<std::string> CommandLineToArgvA()
{
    int argc;
    const auto argv = CommandLineToArgvW(GetCommandLine(), &argc);
    std::vector<std::string> sv(argc);

    for (int i = 0; i < argc; ++i)
    {
        sv[i] = WideCharToAnsi(argv[i]);
    }

    return sv;
}
std::vector<char*> get_array_pointers(std::vector<std::string>& vs)
{
    auto vpv = vs | std::ranges::views::transform([](std::string& s) {return s.data(); });
    return { vpv.begin(), vpv.end() };
}

int WINAPI wWinMain(
    _In_ HINSTANCE hInstance,
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPWSTR lpCmdLine,
    _In_ int nShowCmd
)
{
    auto cmd_args = CommandLineToArgvA();
    auto cmd_args_p = get_array_pointers(cmd_args);
    const int argc = cmd_args_p.size();
    char** argv = cmd_args_p.data();

    const int ret = main(argc, argv);
	return ret;
}


